home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume5 / smallc / part2 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  49.9 KB

  1. Subject: Small C compiler version C3.0R1.1 (part 2 of 3)
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 5, Issue 8
  6. Submitted by: genrad!linus!mnetor!clewis (Chris Lewis)
  7.  
  8. #! /bin/sh
  9. # This is a shell archive, meaning:
  10. # 1. Remove everything above the #! /bin/sh line.
  11. # 2. Save the resulting text in a file.
  12. # 3. Execute the file with /bin/sh (not csh) to create the files:
  13. #    defs.h
  14. #    error.c
  15. #    expr.c
  16. #    function.c
  17. #    gen.c
  18. #    io.c
  19. #    lex.c
  20. #    main.c
  21. #    preproc.c
  22. #    primary.c
  23. #    stmt.c
  24. #    sym.c
  25. #    while.c
  26. # This archive created: Sun May 18 18:17:13 1986
  27. export PATH; PATH=/bin:$PATH
  28. echo shar: extracting "'defs.h'" '(1982 characters)'
  29. if test -f 'defs.h'
  30. then
  31.     echo shar: will not over-write existing file "'defs.h'"
  32. else
  33. cat << \SHAR_EOF > 'defs.h'
  34. /*    File defs.h: 2.1 (83/03/21,02:07:20) */
  35.  
  36.  
  37. #define    FOREVER    for(;;)
  38. #define    FALSE    0
  39. #define    TRUE    1
  40. #define    NO    0
  41. #define    YES    1
  42.  
  43. /* miscellaneous */
  44.  
  45. #define    EOS    0
  46. #define    EOL    10
  47. #define    BKSP    8
  48. #define    CR    13
  49. #define    FFEED    12
  50. #define TAB    9
  51.  
  52. /* symbol table parameters */
  53.  
  54. #define    SYMSIZ    14
  55. #define    SYMTBSZ    2800
  56. #define    NUMGLBS    150
  57. #define    STARTGLB    symtab
  58. #define    ENDGLB    (STARTGLB+NUMGLBS*SYMSIZ)
  59. #define    STARTLOC    (ENDGLB+SYMSIZ)
  60. #define    ENDLOC    (symtab+SYMTBSZ-SYMSIZ)
  61.  
  62. /* symbol table entry format */
  63.  
  64. #define    NAME    0
  65. #define    IDENT    9
  66. #define    TYPE    10
  67. #define    STORAGE    11
  68. #define    OFFSET    12
  69.  
  70. /* system-wide name size (for symbols) */
  71.  
  72. #define    NAMESIZE    9
  73. #define    NAMEMAX    8
  74.  
  75. /* possible entries for "ident" */
  76.  
  77. #define    VARIABLE    1
  78. #define    ARRAY    2
  79. #define    POINTER    3
  80. #define    FUNCTION    4
  81.  
  82. /* possible entries for "type" */
  83.  
  84. #define    CCHAR    1
  85. #define    CINT    2
  86.  
  87. /* possible entries for storage */
  88.  
  89. #define    PUBLIC    1
  90. #define    AUTO    2
  91. #define    EXTERN    3
  92.  
  93. #define    STATIC    4
  94. #define    LSTATIC    5
  95. #define    DEFAUTO    6
  96. /* "do"/"for"/"while"/"switch" statement stack */
  97.  
  98. #define    WSTABSZ    100
  99. #define    WSSIZ    7
  100. #define    WSMAX    ws+WSTABSZ-WSSIZ
  101.  
  102. /* entry offsets in "do"/"for"/"while"/"switch" stack */
  103.  
  104. #define    WSSYM    0
  105. #define    WSSP    1
  106. #define    WSTYP    2
  107. #define    WSCASEP    3
  108. #define    WSTEST    3
  109. #define    WSINCR    4
  110. #define    WSDEF    4
  111. #define    WSBODY    5
  112. #define    WSTAB    5
  113. #define    WSEXIT    6
  114.  
  115. /* possible entries for "wstyp" */
  116.  
  117. #define    WSWHILE    0
  118. #define    WSFOR    1
  119. #define    WSDO    2
  120. #define    WSSWITCH    3
  121.  
  122. /* "switch" label stack */
  123.  
  124. #define    SWSTSZ    100
  125.  
  126. /* literal pool */
  127.  
  128. #define    LITABSZ    2000
  129. #define    LITMAX    LITABSZ-1
  130.  
  131. /* input line */
  132.  
  133. #define    LINESIZE    150
  134. #define    LINEMAX    (LINESIZE-1)
  135. #define    MPMAX    LINEMAX
  136.  
  137. /* macro (define) pool */
  138.  
  139. #define    MACQSIZE    1000
  140. #define    MACMAX    (MACQSIZE-1)
  141.  
  142. /* "include" stack */
  143.  
  144. #define    INCLSIZ    3
  145.  
  146. /* statement types (tokens) */
  147.  
  148. #define    STIF    1
  149. #define    STWHILE    2
  150. #define    STRETURN    3
  151. #define    STBREAK    4
  152. #define    STCONT    5
  153. #define    STASM    6
  154. #define    STEXP    7
  155. #define    STDO    8
  156. #define    STFOR    9
  157. #define    STSWITCH    10
  158.  
  159. #define    DEFLIB    inclib()
  160. SHAR_EOF
  161. if test 1982 -ne "`wc -c < 'defs.h'`"
  162. then
  163.     echo shar: error transmitting "'defs.h'" '(should have been 1982 characters)'
  164. fi
  165. fi
  166. echo shar: extracting "'error.c'" '(552 characters)'
  167. if test -f 'error.c'
  168. then
  169.     echo shar: will not over-write existing file "'error.c'"
  170. else
  171. cat << \SHAR_EOF > 'error.c'
  172. /*    File error.c: 2.1 (83/03/20,16:02:00) */
  173. /*% cc -O -c %
  174.  *
  175.  */
  176.  
  177. #include <stdio.h>
  178. #include "defs.h"
  179. #include "data.h"
  180.  
  181. error (ptr)
  182. char    ptr[];
  183. {
  184.     FILE *tempfile;
  185.  
  186.     tempfile = output;
  187.     output = stdout;
  188.     doerror(ptr);
  189.     output = tempfile;
  190.     doerror(ptr);
  191.     errcnt++;
  192. }
  193. doerror(ptr) char *ptr; {
  194.     int k;
  195.     comment ();
  196.     outstr (line);
  197.     nl ();
  198.     comment ();
  199.     k = 0;
  200.     while (k < lptr) {
  201.         if (line[k] == 9)
  202.             tab ();
  203.         else
  204.             outbyte (' ');
  205.         k++;
  206.     }
  207.     outbyte ('^');
  208.     nl ();
  209.     comment ();
  210.     outstr ("******  ");
  211.     outstr (ptr);
  212.     outstr ("  ******");
  213.     nl ();
  214. }
  215. SHAR_EOF
  216. if test 552 -ne "`wc -c < 'error.c'`"
  217. then
  218.     echo shar: error transmitting "'error.c'" '(should have been 552 characters)'
  219. fi
  220. fi
  221. echo shar: extracting "'expr.c'" '(10028 characters)'
  222. if test -f 'expr.c'
  223. then
  224.     echo shar: will not over-write existing file "'expr.c'"
  225. else
  226. cat << \SHAR_EOF > 'expr.c'
  227. /*    File expr.c: 2.2 (83/06/21,11:24:26) */
  228. /*% cc -O -c %
  229.  *
  230.  */
  231.  
  232. #include <stdio.h>
  233. #include "defs.h"
  234. #include "data.h"
  235.  
  236. /*
  237.  *    lval[0] - symbol table address, else 0 for constant
  238.  *    lval[1] - type indirect object to fetch, else 0 for static object
  239.  *    lval[2] - type pointer or array, else 0
  240.  */
  241.  
  242. expression (comma)
  243. int    comma;
  244. {
  245.     int    lval[3];
  246.  
  247.     do {
  248.         if (heir1 (lval))
  249.             rvalue (lval);
  250.         if (!comma)
  251.             return;
  252.     } while (match (","));
  253. }
  254.  
  255. heir1 (lval)
  256. int    lval[];
  257. {
  258.     int    k, lval2[3];
  259.     char    fc;
  260.  
  261.     k = heir1a (lval);
  262.     if (match ("=")) {
  263.         if (k == 0) {
  264.             needlval ();
  265.             return (0);
  266.         }
  267.         if (lval[1])
  268.             gpush ();
  269.         if (heir1 (lval2))
  270.             rvalue (lval2);
  271.         store (lval);
  272.         return (0);
  273.     } else
  274.     {    
  275.         fc = ch();
  276.         if  (match ("-=") ||
  277.             match ("+=") ||
  278.             match ("*=") ||
  279.             match ("/=") ||
  280.             match ("%=") ||
  281.             match (">>=") ||
  282.             match ("<<=") ||
  283.             match ("&=") ||
  284.             match ("^=") ||
  285.             match ("|=")) {
  286.             if (k == 0) {
  287.                 needlval ();
  288.                 return (0);
  289.             }
  290.             if (lval[1])
  291.                 gpush ();
  292.             rvalue (lval);
  293.             gpush ();
  294.             if (heir1 (lval2))
  295.                 rvalue (lval2);
  296.             switch (fc) {
  297.                 case '-':    {
  298.                     if (dbltest(lval,lval2))
  299.                         gaslint();
  300.                     gsub();
  301.                     result (lval, lval2);
  302.                     break;
  303.                 }
  304.                 case '+':    {
  305.                     if (dbltest(lval,lval2))
  306.                         gaslint();
  307.                     gadd (lval,lval2);
  308.                     result(lval,lval2);
  309.                     break;
  310.                 }
  311.                 case '*':    gmult (); break;
  312.                 case '/':    gdiv (); break;
  313.                 case '%':    gmod (); break;
  314.                 case '>':    gasr (); break;
  315.                 case '<':    gasl (); break;
  316.                 case '&':    gand (); break;
  317.                 case '^':    gxor (); break;
  318.                 case '|':    gor (); break;
  319.             }
  320.             store (lval);
  321.             return (0);
  322.         } else
  323.             return (k);
  324.     }
  325. }
  326.  
  327. heir1a (lval)
  328. int    lval[];
  329. {
  330.     int    k, lval2[3], lab1, lab2;
  331.  
  332.     k = heir1b (lval);
  333.     blanks ();
  334.     if (ch () != '?')
  335.         return (k);
  336.     if (k)
  337.         rvalue (lval);
  338.     FOREVER
  339.         if (match ("?")) {
  340.             testjump (lab1 = getlabel (), FALSE);
  341.             if (heir1b (lval2))
  342.                 rvalue (lval2);
  343.             jump (lab2 = getlabel ());
  344.             printlabel (lab1);
  345.             col ();
  346.             nl ();
  347.             blanks ();
  348.             if (!match (":")) {
  349.                 error ("missing colon");
  350.                 return (0);
  351.             }
  352.             if (heir1b (lval2))
  353.                 rvalue (lval2);
  354.             printlabel (lab2);
  355.             col ();
  356.             nl ();
  357.         } else
  358.             return (0);
  359. }
  360.  
  361. heir1b (lval)
  362. int    lval[];
  363. {
  364.     int    k, lval2[3], lab;
  365.  
  366.     k = heir1c (lval);
  367.     blanks ();
  368.     if (!sstreq ("||"))
  369.         return (k);
  370.     if (k)
  371.         rvalue (lval);
  372.     FOREVER
  373.         if (match ("||")) {
  374.             testjump (lab = getlabel (), TRUE);
  375.             if (heir1c (lval2))
  376.                 rvalue (lval2);
  377.             printlabel (lab);
  378.             col ();
  379.             nl ();
  380.             gbool();
  381.         } else
  382.             return (0);
  383. }
  384.  
  385. heir1c (lval)
  386. int    lval[];
  387. {
  388.     int    k, lval2[3], lab;
  389.  
  390.     k = heir2 (lval);
  391.     blanks ();
  392.     if (!sstreq ("&&"))
  393.         return (k);
  394.     if (k)
  395.         rvalue (lval);
  396.     FOREVER
  397.         if (match ("&&")) {
  398.             testjump (lab = getlabel (), FALSE);
  399.             if (heir2 (lval2))
  400.                 rvalue (lval2);
  401.             printlabel (lab);
  402.             col ();
  403.             nl ();
  404.             gbool();
  405.         } else
  406.             return (0);
  407. }
  408.  
  409. heir2 (lval)
  410. int    lval[];
  411. {
  412.     int    k, lval2[3];
  413.  
  414.     k = heir3 (lval);
  415.     blanks ();
  416.     if ((ch() != '|') | (nch() == '|') | (nch() == '='))
  417.         return (k);
  418.     if (k)
  419.         rvalue (lval);
  420.     FOREVER {
  421.         if ((ch() == '|') & (nch() != '|') & (nch() != '=')) {
  422.             inbyte ();
  423.             gpush ();
  424.             if (heir3 (lval2))
  425.                 rvalue (lval2);
  426.             gor ();
  427.             blanks();
  428.         } else
  429.             return (0);
  430.     }
  431. }
  432.  
  433. heir3 (lval)
  434. int    lval[];
  435. {
  436.     int    k, lval2[3];
  437.  
  438.     k = heir4 (lval);
  439.     blanks ();
  440.     if ((ch () != '^') | (nch() == '='))
  441.         return (k);
  442.     if (k)
  443.         rvalue (lval);
  444.     FOREVER {
  445.         if ((ch() == '^') & (nch() != '=')){
  446.             inbyte ();
  447.             gpush ();
  448.             if (heir4 (lval2))
  449.                 rvalue (lval2);
  450.             gxor ();
  451.             blanks();
  452.         } else
  453.             return (0);
  454.     }
  455. }
  456.  
  457. heir4 (lval)
  458. int    lval[];
  459. {
  460.     int    k, lval2[3];
  461.  
  462.     k = heir5 (lval);
  463.     blanks ();
  464.     if ((ch() != '&') | (nch() == '|') | (nch() == '='))
  465.         return (k);
  466.     if (k)
  467.         rvalue (lval);
  468.     FOREVER {
  469.         if ((ch() == '&') & (nch() != '&') & (nch() != '=')) {
  470.             inbyte ();
  471.             gpush ();
  472.             if (heir5 (lval2))
  473.                 rvalue (lval2);
  474.             gand ();
  475.             blanks();
  476.         } else
  477.             return (0);
  478.     }
  479. }
  480.  
  481. heir5 (lval)
  482. int    lval[];
  483. {
  484.     int    k, lval2[3];
  485.  
  486.     k = heir6 (lval);
  487.     blanks ();
  488.     if (!sstreq ("==") &
  489.         !sstreq ("!="))
  490.         return (k);
  491.     if (k)
  492.         rvalue (lval);
  493.     FOREVER {
  494.         if (match ("==")) {
  495.             gpush ();
  496.             if (heir6 (lval2))
  497.                 rvalue (lval2);
  498.             geq ();
  499.         } else if (match ("!=")) {
  500.             gpush ();
  501.             if (heir6 (lval2))
  502.                 rvalue (lval2);
  503.             gne ();
  504.         } else
  505.             return (0);
  506.     }
  507. }
  508.  
  509. heir6 (lval)
  510. int    lval[];
  511. {
  512.     int    k, lval2[3];
  513.  
  514.     k = heir7 (lval);
  515.     blanks ();
  516.     if (!sstreq ("<") &&
  517.         !sstreq ("<=") &&
  518.         !sstreq (">=") &&
  519.         !sstreq (">"))
  520.         return (k);
  521.     if (sstreq ("<<") || sstreq (">>"))
  522.         return (k);
  523.     if (k)
  524.         rvalue (lval);
  525.     FOREVER {
  526.         if (match ("<=")) {
  527.             gpush ();
  528.             if (heir7 (lval2))
  529.                 rvalue (lval2);
  530.             if (lval[2] || lval2[2]) {
  531.                 gule ();
  532.                 continue;
  533.             }
  534.             gle ();
  535.         } else if (match (">=")) {
  536.             gpush ();
  537.             if (heir7 (lval2))
  538.                 rvalue (lval2);
  539.             if (lval[2] || lval2[2]) {
  540.                 guge ();
  541.                 continue;
  542.             }
  543.             gge ();
  544.         } else if ((sstreq ("<")) &&
  545.                !sstreq ("<<")) {
  546.             inbyte ();
  547.             gpush ();
  548.             if (heir7 (lval2))
  549.                 rvalue (lval2);
  550.             if (lval[2] || lval2[2]) {
  551.                 gult ();
  552.                 continue;
  553.             }
  554.             glt ();
  555.         } else if ((sstreq (">")) &&
  556.                !sstreq (">>")) {
  557.             inbyte ();
  558.             gpush ();
  559.             if (heir7 (lval2))
  560.                 rvalue (lval2);
  561.             if (lval[2] || lval2[2]) {
  562.                 gugt ();
  563.                 continue;
  564.             }
  565.             ggt ();
  566.         } else
  567.             return (0);
  568.         blanks ();
  569.     }
  570. }
  571.  
  572. heir7 (lval)
  573. int    lval[];
  574. {
  575.     int    k, lval2[3];
  576.  
  577.     k = heir8 (lval);
  578.     blanks ();
  579.     if (!sstreq (">>") &&
  580.         !sstreq ("<<") || sstreq(">>=") || sstreq("<<="))
  581.         return (k);
  582.     if (k)
  583.         rvalue (lval);
  584.     FOREVER {
  585.         if (sstreq(">>") && ! sstreq(">>=")) {
  586.             inbyte(); inbyte();
  587.             gpush ();
  588.             if (heir8 (lval2))
  589.                 rvalue (lval2);
  590.             gasr ();
  591.         } else if (sstreq("<<") && ! sstreq("<<=")) {
  592.             inbyte(); inbyte();
  593.             gpush ();
  594.             if (heir8 (lval2))
  595.                 rvalue (lval2);
  596.             gasl ();
  597.         } else
  598.             return (0);
  599.         blanks();
  600.     }
  601. }
  602.  
  603. heir8 (lval)
  604. int    lval[];
  605. {
  606.     int    k, lval2[3];
  607.  
  608.     k = heir9 (lval);
  609.     blanks ();
  610.     if ((ch () != '+') & (ch () != '-') | nch() == '=')
  611.         return (k);
  612.     if (k)
  613.         rvalue (lval);
  614.     FOREVER {
  615.         if (match ("+")) {
  616.             gpush ();
  617.             if (heir9 (lval2))
  618.                 rvalue (lval2);
  619.             /* if left is pointer and right is int, scale right */
  620.             if (dbltest (lval, lval2))
  621.                 gaslint ();
  622.             /* will scale left if right int pointer and left int */
  623.             gadd (lval,lval2);
  624.             result (lval, lval2);
  625.         } else if (match ("-")) {
  626.             gpush ();
  627.             if (heir9 (lval2))
  628.                 rvalue (lval2);
  629.             /* if dbl, can only be: pointer - int, or
  630.                         pointer - pointer, thus,
  631.                 in first case, int is scaled up,
  632.                 in second, result is scaled down. */
  633.             if (dbltest (lval, lval2))
  634.                 gaslint ();
  635.             gsub ();
  636.             /* if both pointers, scale result */
  637.             if ((lval[2] == CINT) && (lval2[2] == CINT)) {
  638.                 gasrint(); /* divide by intsize */
  639.             }
  640.             result (lval, lval2);
  641.         } else
  642.             return (0);
  643.     }
  644. }
  645.  
  646. heir9 (lval)
  647. int    lval[];
  648. {
  649.     int    k, lval2[3];
  650.  
  651.     k = heir10 (lval);
  652.     blanks ();
  653.     if (((ch () != '*') && (ch () != '/') &&
  654.         (ch () != '%')) || (nch() == '='))
  655.         return (k);
  656.     if (k)
  657.         rvalue (lval);
  658.     FOREVER {
  659.         if (match ("*")) {
  660.             gpush ();
  661.             if (heir10 (lval2))
  662.                 rvalue (lval2);
  663.             gmult ();
  664.         } else if (match ("/")) {
  665.             gpush ();
  666.             if (heir10 (lval2))
  667.                 rvalue (lval2);
  668.             gdiv ();
  669.         } else if (match ("%")) {
  670.             gpush ();
  671.             if (heir10 (lval2))
  672.                 rvalue (lval2);
  673.             gmod ();
  674.         } else
  675.             return (0);
  676.     }
  677. }
  678.  
  679. heir10 (lval)
  680. int    lval[];
  681. {
  682.     int    k;
  683.     char    *ptr;
  684.  
  685.     if (match ("++")) {
  686.         if ((k = heir10 (lval)) == 0) {
  687.             needlval ();
  688.             return (0);
  689.         }
  690.         if (lval[1])
  691.             gpush ();
  692.         rvalue (lval);
  693.         ginc (lval);
  694.         store (lval);
  695.         return (0);
  696.     } else if (match ("--")) {
  697.         if ((k = heir10 (lval)) == 0) {
  698.             needlval ();
  699.             return (0);
  700.         }
  701.         if (lval[1])
  702.             gpush ();
  703.         rvalue (lval);
  704.         gdec (lval);
  705.         store (lval);
  706.         return (0);
  707.     } else if (match ("-")) {
  708.         k = heir10 (lval);
  709.         if (k)
  710.             rvalue (lval);
  711.         gneg ();
  712.         return (0);
  713.     } else if (match ("~")) {
  714.         k = heir10 (lval);
  715.         if (k)
  716.             rvalue (lval);
  717.         gcom ();
  718.         return (0);
  719.     } else if (match ("!")) {
  720.         k = heir10 (lval);
  721.         if (k)
  722.             rvalue (lval);
  723.         glneg ();
  724.         return (0);
  725.     } else if (ch()=='*' && nch() != '=') {
  726.         inbyte();
  727.         k = heir10 (lval);
  728.         if (k)
  729.             rvalue (lval);
  730.         if (ptr = lval[0])
  731.             lval[1] = ptr[TYPE];
  732.         else
  733.             lval[1] = CINT;
  734.         lval[2] = 0;  /* flag as not pointer or array */
  735.         return (1);
  736.     } else if (ch()=='&' && nch()!='&' && nch()!='=') {
  737.         inbyte();
  738.         k = heir10 (lval);
  739.         if (k == 0) {
  740.             error ("illegal address");
  741.             return (0);
  742.         }
  743.         ptr = lval[0];
  744.         lval[2] = ptr[TYPE];
  745.         if (lval[1])
  746.             return (0);
  747.         /* global and non-array */
  748.         immed ();
  749.         prefix ();
  750.         outstr (ptr = lval[0]);
  751.         nl ();
  752.         lval[1] = ptr[TYPE];
  753.         return (0);
  754.     } else {
  755.         k = heir11 (lval);
  756.         if (match ("++")) {
  757.             if (k == 0) {
  758.                 needlval ();
  759.                 return (0);
  760.             }
  761.             if (lval[1])
  762.                 gpush ();
  763.             rvalue (lval);
  764.             ginc (lval);
  765.             store (lval);
  766.             gdec (lval);
  767.             return (0);
  768.         } else if (match ("--")) {
  769.             if (k == 0) {
  770.                 needlval ();
  771.                 return (0);
  772.             }
  773.             if (lval[1])
  774.                 gpush ();
  775.             rvalue (lval);
  776.             gdec (lval);
  777.             store (lval);
  778.             ginc (lval);
  779.             return (0);
  780.         } else
  781.             return (k);
  782.     }
  783. }
  784.  
  785. heir11 (lval)
  786. int    *lval;
  787. {
  788.     int    k;
  789.     char    *ptr;
  790.  
  791.     k = primary (lval);
  792.     ptr = lval[0];
  793.     blanks ();
  794.     if ((ch () == '[') | (ch () == '('))
  795.         FOREVER {
  796.             if (match ("[")) {
  797.                 if (ptr == 0) {
  798.                     error ("can't subscript");
  799.                     junk ();
  800.                     needbrack ("]");
  801.                     return (0);
  802.                 } else if (ptr[IDENT] == POINTER)
  803.                     rvalue (lval);
  804.                 else if (ptr[IDENT] != ARRAY) {
  805.                     error ("can't subscript");
  806.                     k = 0;
  807.                 }
  808.                 gpush ();
  809.                 expression (YES);
  810.                 needbrack ("]");
  811.                 if (ptr[TYPE] == CINT)
  812.                     gaslint ();
  813.                 gadd (NULL,NULL);
  814.                 lval[0] = 0;
  815.                 lval[1] = ptr[TYPE];
  816.                 k = 1;
  817.             } else if (match ("(")) {
  818.                 if (ptr == 0)
  819.                     callfunction (0);
  820.                 else if (ptr[IDENT] != FUNCTION) {
  821.                     rvalue (lval);
  822.                     callfunction (0);
  823.                 } else
  824.                     callfunction (ptr);
  825.                 k = lval[0] = 0;
  826.             } else
  827.                 return (k);
  828.         }
  829.     if (ptr == 0)
  830.         return (k);
  831.     if (ptr[IDENT] == FUNCTION) {
  832.         immed ();
  833.         prefix ();
  834.         outstr (ptr);
  835.         nl ();
  836.         return (0);
  837.     }
  838.     return (k);
  839. }
  840. SHAR_EOF
  841. if test 10028 -ne "`wc -c < 'expr.c'`"
  842. then
  843.     echo shar: error transmitting "'expr.c'" '(should have been 10028 characters)'
  844. fi
  845. fi
  846. echo shar: extracting "'function.c'" '(2643 characters)'
  847. if test -f 'function.c'
  848. then
  849.     echo shar: will not over-write existing file "'function.c'"
  850. else
  851. cat << \SHAR_EOF > 'function.c'
  852. /*    File function.c: 2.1 (83/03/20,16:02:04) */
  853. /*% cc -O -c %
  854.  *
  855.  */
  856.  
  857. #include <stdio.h>
  858. #include "defs.h"
  859. #include "data.h"
  860.  
  861. /*
  862.  *    begin a function
  863.  *
  864.  *    called from "parse", this routine tries to make a function out
  865.  *    of what follows
  866.  *    modified version.  p.l. woods
  867.  *
  868.  */
  869. int argtop;
  870. newfunc ()
  871. {
  872.     char    n[NAMESIZE], *ptr;
  873.     fexitlab = getlabel();
  874.  
  875.     if (!symname (n) ) {
  876.         error ("illegal function or declaration");
  877.         kill ();
  878.         return;
  879.     }
  880.     if (ptr = findglb (n)) {
  881.         if (ptr[IDENT] != FUNCTION)
  882.             multidef (n);
  883.         else if (ptr[OFFSET] == FUNCTION)
  884.             multidef (n);
  885.         else
  886.             ptr[OFFSET] = FUNCTION;
  887.     } else
  888.         addglb (n, FUNCTION, CINT, FUNCTION, PUBLIC);
  889.     prologue ();
  890.     if (!match ("("))
  891.         error ("missing open paren");
  892.     prefix ();
  893.     outstr (n);
  894.     col ();
  895.     nl ();
  896.     locptr = STARTLOC;
  897.     argstk = 0;
  898.     while (!match (")")) {
  899.         if (symname (n)) {
  900.             if (findloc (n))
  901.                 multidef (n);
  902.             else {
  903.                 addloc (n, 0, 0, argstk, AUTO);
  904.                 argstk = argstk + intsize();
  905.             }
  906.         } else {
  907.             error ("illegal argument name");
  908.             junk ();
  909.         }
  910.         blanks ();
  911.         if (!streq (line + lptr, ")")) {
  912.             if (!match (","))
  913.                 error ("expected comma");
  914.         }
  915.         if (endst ())
  916.             break;
  917.     }
  918.     stkp = 0;
  919.     argtop = argstk;
  920.     while (argstk) {
  921.         if (amatch ("register", 8)) {
  922.             if (amatch("char", 4)) 
  923.                 getarg(CCHAR);
  924.             else if (amatch ("int", 3))
  925.                 getarg(CINT);
  926.             else
  927.                 getarg(CINT);
  928.             ns();
  929.         } else if (amatch ("char", 4)) {
  930.             getarg (CCHAR);
  931.             ns ();
  932.         } else if (amatch ("int", 3)) {
  933.             getarg (CINT);
  934.             ns ();
  935.         } else {
  936.             error ("wrong number args");
  937.             break;
  938.         }
  939.     }
  940.     statement(YES);
  941.     printlabel(fexitlab);
  942.     col();
  943.     nl();
  944.     modstk (0);
  945.     gret ();
  946.     stkp = 0;
  947.     locptr = STARTLOC;
  948. }
  949.  
  950. /*
  951.  *    declare argument types
  952.  *
  953.  *    called from "newfunc", this routine add an entry in the local
  954.  *    symbol table for each named argument
  955.  *    completely rewritten version.  p.l. woods
  956.  *
  957.  */
  958. getarg (t)
  959. int    t;
  960. {
  961.     int    j, legalname, address;
  962.     char    n[NAMESIZE], c, *argptr;
  963.  
  964.     FOREVER {
  965.         if (argstk == 0)
  966.             return;
  967.         if (match ("*"))
  968.             j = POINTER;
  969.         else
  970.             j = VARIABLE;
  971.         if (!(legalname = symname (n)))
  972.             illname ();
  973.         if (match ("[")) {
  974.             while (inbyte () != ']')
  975.                 if (endst ())
  976.                     break;
  977.             j = POINTER;
  978.         }
  979.         if (legalname) {
  980.             if (argptr = findloc (n)) {
  981.                 argptr[IDENT] = j;
  982.                 argptr[TYPE] = t;
  983.                 address = argtop - glint(argptr);
  984.                 if (t == CCHAR && j == VARIABLE)
  985.                     address = address + byteoff();
  986.                 argptr[OFFSET] = (address) & 0xff;
  987.                 argptr[OFFSET + 1] = (address >> 8) & 0xff;
  988.             } else
  989.                 error ("expecting argument name");
  990.         }
  991.         argstk = argstk - intsize();
  992.         if (endst ())
  993.             return;
  994.         if (!match (","))
  995.             error ("expected comma");
  996.     }
  997. }
  998. SHAR_EOF
  999. if test 2643 -ne "`wc -c < 'function.c'`"
  1000. then
  1001.     echo shar: error transmitting "'function.c'" '(should have been 2643 characters)'
  1002. fi
  1003. fi
  1004. echo shar: extracting "'gen.c'" '(1495 characters)'
  1005. if test -f 'gen.c'
  1006. then
  1007.     echo shar: will not over-write existing file "'gen.c'"
  1008. else
  1009. cat << \SHAR_EOF > 'gen.c'
  1010. /*    File gen.c: 2.1 (83/03/20,16:02:06) */
  1011. /*% cc -O -c %
  1012.  *
  1013.  */
  1014.  
  1015. #include <stdio.h>
  1016. #include "defs.h"
  1017. #include "data.h"
  1018.  
  1019.  
  1020. /*
  1021.  *    return next available internal label number
  1022.  *
  1023.  */
  1024. getlabel ()
  1025. {
  1026.     return (nxtlab++);
  1027. }
  1028.  
  1029. /*
  1030.  *    print specified number as label
  1031.  */
  1032. printlabel (label)
  1033. int    label;
  1034. {
  1035.     olprfix ();
  1036.     outdec (label);
  1037. }
  1038.  
  1039. /*
  1040.  *    glabel - generate label
  1041.  */
  1042. glabel (lab)
  1043. char    *lab;
  1044. {
  1045.     prefix ();
  1046.     outstr (lab);
  1047.     col ();
  1048.     nl ();
  1049. }
  1050.  
  1051. /*
  1052.  *    gnlabel - generate numeric label
  1053.  */
  1054. gnlabel (nlab)
  1055. int    nlab;
  1056. {
  1057.     printlabel (nlab);
  1058.     col ();
  1059.     nl ();
  1060. }
  1061.  
  1062. outbyte (c)
  1063. char    c;
  1064. {
  1065.     if (c == 0)
  1066.         return (0);
  1067.     fputc (c, output);
  1068.     return (c);
  1069. }
  1070.  
  1071. outstr (ptr)
  1072. char    ptr[];
  1073. {
  1074.     int    k;
  1075.  
  1076.     k = 0;
  1077.     while (outbyte (ptr[k++]));
  1078. }
  1079.  
  1080.  
  1081. tab ()
  1082. {
  1083.     outbyte (9);
  1084. }
  1085.  
  1086. ol (ptr)
  1087. char    ptr[];
  1088. {
  1089.     ot (ptr);
  1090.     nl ();
  1091. }
  1092.  
  1093. ot (ptr)
  1094. char    ptr[];
  1095. {
  1096.     tab ();
  1097.     outstr (ptr);
  1098. }
  1099.  
  1100. outdec (number)
  1101. int    number;
  1102. {
  1103.     int    k, zs;
  1104.     char    c;
  1105.  
  1106.     if (number == -32768) {
  1107.         outstr ("-32768");
  1108.         return;
  1109.     }
  1110.     zs = 0;
  1111.     k = 10000;
  1112.     if (number < 0) {
  1113.         number = (-number);
  1114.         outbyte ('-');
  1115.     }
  1116.     while (k >= 1) {
  1117.         c = number / k + '0';
  1118.         if ((c != '0' | (k == 1) | zs)) {
  1119.             zs = 1;
  1120.             outbyte (c);
  1121.         }
  1122.         number = number % k;
  1123.         k = k / 10;
  1124.     }
  1125. }
  1126.         
  1127. store (lval)
  1128. int    *lval;
  1129. {
  1130.     if (lval[1] == 0)
  1131.         putmem (lval[0]);
  1132.     else
  1133.         putstk (lval[1]);
  1134. }
  1135.  
  1136. rvalue (lval)
  1137. int    *lval;
  1138. {
  1139.     if ((lval[0] != 0) & (lval[1] == 0))
  1140.         getmem (lval[0]);
  1141.     else
  1142.         indirect (lval[1]);
  1143. }
  1144.  
  1145. test (label, ft)
  1146. int    label,
  1147.     ft;
  1148. {
  1149.     needbrack ("(");
  1150.     expression (YES);
  1151.     needbrack (")");
  1152.     testjump (label, ft);
  1153. }
  1154. SHAR_EOF
  1155. if test 1495 -ne "`wc -c < 'gen.c'`"
  1156. then
  1157.     echo shar: error transmitting "'gen.c'" '(should have been 1495 characters)'
  1158. fi
  1159. fi
  1160. echo shar: extracting "'io.c'" '(2032 characters)'
  1161. if test -f 'io.c'
  1162. then
  1163.     echo shar: will not over-write existing file "'io.c'"
  1164. else
  1165. cat << \SHAR_EOF > 'io.c'
  1166. /*    File io.c: 2.1 (83/03/20,16:02:07) */
  1167. /*% cc -O -c %
  1168.  *
  1169.  */
  1170.  
  1171. #include <stdio.h>
  1172. #include "defs.h"
  1173. #include "data.h"
  1174.  
  1175. /*
  1176.  *    open input file
  1177.  */
  1178. openin (p) char *p;
  1179. {
  1180.     strcpy(fname, p);
  1181.     fixname (fname);
  1182.     if (!checkname (fname))
  1183.         return (NO);
  1184.     if ((input = fopen (fname, "r")) == NULL) {
  1185.         pl ("Open failure\n");
  1186.         return (NO);
  1187.     }
  1188.     kill ();
  1189.     return (YES);
  1190. }
  1191.  
  1192. /*
  1193.  *    open output file
  1194.  */
  1195. openout ()
  1196. {
  1197.     outfname (fname);
  1198.     if ((output = fopen (fname, "w")) == NULL) {
  1199.         pl ("Open failure");
  1200.         return (NO);
  1201.     }
  1202.     kill ();
  1203.     return (YES);
  1204. }
  1205.  
  1206. /*
  1207.  *    change input filename to output filename
  1208.  */
  1209. outfname (s)
  1210. char    *s;
  1211. {
  1212.     while (*s)
  1213.         s++;
  1214.     *--s = 's';
  1215. }
  1216.  
  1217. /*
  1218.  *    remove NL from filenames
  1219.  *
  1220.  */
  1221. fixname (s)
  1222. char    *s;
  1223. {
  1224.     while (*s && *s++ != EOL);
  1225.     if (!*s) return;
  1226.     *(--s) = 0;
  1227. }
  1228.  
  1229. /*
  1230.  *    check that filename is "*.c"
  1231.  */
  1232. checkname (s)
  1233. char    *s;
  1234. {
  1235.     while (*s)
  1236.         s++;
  1237.     if (*--s != 'c')
  1238.         return (NO);
  1239.     if (*--s != '.')
  1240.         return (NO);
  1241.     return (YES);
  1242. }
  1243.  
  1244. kill ()
  1245. {
  1246.     lptr = 0;
  1247.     line[lptr] = 0;
  1248. }
  1249.  
  1250. inline ()
  1251. {
  1252.     int    k;
  1253.     FILE    *unit;
  1254.  
  1255.     FOREVER {
  1256.         if (feof (input))
  1257.             return;
  1258.         if ((unit = input2) == NULL)
  1259.             unit = input;
  1260.         kill ();
  1261.         while ((k = fgetc (unit)) != EOF) {
  1262.             if ((k == EOL) | (lptr >= LINEMAX))
  1263.                 break;
  1264.             line[lptr++] = k;
  1265.         }
  1266.         line[lptr] = 0;
  1267.         if (k <= 0)
  1268.             if (input2 != NULL) {
  1269.                 input2 = inclstk[--inclsp];
  1270.                 fclose (unit);
  1271.             }
  1272.         if (lptr) {
  1273.             if ((ctext) & (cmode)) {
  1274.                 comment ();
  1275.                 outstr (line);
  1276.                 nl ();
  1277.             }
  1278.             lptr = 0;
  1279.             return;
  1280.         }
  1281.     }
  1282. }
  1283.  
  1284. inbyte ()
  1285. {
  1286.     while (ch () == 0) {
  1287.         if (feof (input))
  1288.             return (0);
  1289.         preprocess ();
  1290.     }
  1291.     return (gch ());
  1292. }
  1293.  
  1294. inchar ()
  1295. {
  1296.     if (ch () == 0)
  1297.         inline ();
  1298.     if (feof (input))
  1299.         return (0);
  1300.     return (gch ());
  1301. }
  1302.  
  1303. gch ()
  1304. {
  1305.     if (ch () == 0)
  1306.         return (0);
  1307.     else
  1308.         return (line[lptr++] & 127);
  1309. }
  1310.  
  1311. nch ()
  1312. {
  1313.     if (ch () == 0)
  1314.         return (0);
  1315.     else
  1316.         return (line[lptr + 1] & 127);
  1317. }
  1318.  
  1319. ch ()
  1320. {
  1321.     return (line[lptr] & 127);
  1322. }
  1323.  
  1324. /*
  1325.  *    print a carriage return and a string only to console
  1326.  *
  1327.  */
  1328. pl (str)
  1329. char    *str;
  1330. {
  1331.     int    k;
  1332.  
  1333.     k = 0;
  1334.     putchar (EOL);
  1335.     while (str[k])
  1336.         putchar (str[k++]);
  1337. }
  1338. SHAR_EOF
  1339. if test 2032 -ne "`wc -c < 'io.c'`"
  1340. then
  1341.     echo shar: error transmitting "'io.c'" '(should have been 2032 characters)'
  1342. fi
  1343. fi
  1344. echo shar: extracting "'lex.c'" '(2029 characters)'
  1345. if test -f 'lex.c'
  1346. then
  1347.     echo shar: will not over-write existing file "'lex.c'"
  1348. else
  1349. cat << \SHAR_EOF > 'lex.c'
  1350. /*    File lex.c: 2.1 (83/03/20,16:02:09) */
  1351. /*% cc -O -c %
  1352.  *
  1353.  */
  1354.  
  1355. #include <stdio.h>
  1356. #include "defs.h"
  1357. #include "data.h"
  1358.  
  1359. /*
  1360.  *    semicolon enforcer
  1361.  *
  1362.  *    called whenever syntax requires a semicolon
  1363.  *
  1364.  */
  1365. ns ()
  1366. {
  1367.     if (!match (";"))
  1368.         error ("missing semicolon");
  1369. }
  1370.  
  1371. junk ()
  1372. {
  1373.     if (an (inbyte ()))
  1374.         while (an (ch ()))
  1375.             gch ();
  1376.     else
  1377.         while (an (ch ())) {
  1378.             if (ch () == 0)
  1379.                 break;
  1380.             gch ();
  1381.         }
  1382.     blanks ();
  1383. }
  1384.  
  1385. endst ()
  1386. {
  1387.     blanks ();
  1388.     return ((streq (line + lptr, ";") | (ch () == 0)));
  1389. }
  1390.  
  1391. needbrack (str)
  1392. char    *str;
  1393. {
  1394.     if (!match (str)) {
  1395.         error ("missing bracket");
  1396.         comment ();
  1397.         outstr (str);
  1398.         nl ();
  1399.     }
  1400. }
  1401.  
  1402. /*
  1403.  *    test if given character is alpha
  1404.  *
  1405.  */
  1406. alpha (c)
  1407. char    c;
  1408. {
  1409.     c = c & 127;
  1410.     return (((c >= 'a') & (c <= 'z')) |
  1411.         ((c >= 'A') & (c <= 'Z')) |
  1412.         (c == '_'));
  1413. }
  1414.  
  1415. /*
  1416.  *    test if given character is numeric
  1417.  *
  1418.  */
  1419. numeric (c)
  1420. char    c;
  1421. {
  1422.     c = c & 127;
  1423.     return ((c >= '0') & (c <= '9'));
  1424. }
  1425.  
  1426. /*
  1427.  *    test if given character is alphanumeric
  1428.  *
  1429.  */
  1430. an (c)
  1431. char    c;
  1432. {
  1433.     return ((alpha (c)) | (numeric (c)));
  1434. }
  1435.  
  1436. sstreq (str1) char *str1; {
  1437.     return (streq(line + lptr, str1));
  1438. }
  1439.  
  1440. streq (str1, str2)
  1441. char    str1[], str2[];
  1442. {
  1443.     int    k;
  1444.  
  1445.     k = 0;
  1446.     while (str2[k]) {
  1447.         if ((str1[k] != str2[k]))
  1448.             return (0);
  1449.         k++;
  1450.     }
  1451.     return (k);
  1452. }
  1453.  
  1454. astreq (str1, str2, len)
  1455. char    str1[], str2[];
  1456. int    len;
  1457. {
  1458.     int    k;
  1459.  
  1460.     k = 0;
  1461.     while (k < len) {
  1462.         if ((str1[k] != str2[k]))
  1463.             break;
  1464.         if (str1[k] == 0)
  1465.             break;
  1466.         if (str2[k] == 0)
  1467.             break;
  1468.         k++;
  1469.     }
  1470.     if (an (str1[k]))
  1471.         return (0);
  1472.     if (an (str2[k]))
  1473.         return (0);
  1474.     return (k);
  1475. }
  1476.  
  1477. match (lit)
  1478. char    *lit;
  1479. {
  1480.     int    k;
  1481.  
  1482.     blanks ();
  1483.     if (k = streq (line + lptr, lit)) {
  1484.         lptr = lptr + k;
  1485.         return (1);
  1486.     }
  1487.     return (0);
  1488. }
  1489.  
  1490. amatch (lit, len)
  1491. char    *lit;
  1492. int    len;
  1493. {
  1494.     int    k;
  1495.  
  1496.     blanks ();
  1497.     if (k = astreq (line + lptr, lit, len)) {
  1498.         lptr = lptr + k;
  1499.         while (an (ch ()))
  1500.             inbyte ();
  1501.         return (1);
  1502.     }
  1503.     return (0);
  1504. }
  1505.  
  1506. blanks ()
  1507. {
  1508.     FOREVER {
  1509.         while (ch () == 0) {
  1510.             preprocess ();
  1511.             if (feof (input))
  1512.                 break;
  1513.         }
  1514.         if (ch () == ' ')
  1515.             gch ();
  1516.         else if (ch () == 9)
  1517.             gch ();
  1518.         else
  1519.             return;
  1520.     }
  1521. }
  1522. SHAR_EOF
  1523. if test 2029 -ne "`wc -c < 'lex.c'`"
  1524. then
  1525.     echo shar: error transmitting "'lex.c'" '(should have been 2029 characters)'
  1526. fi
  1527. fi
  1528. echo shar: extracting "'main.c'" '(4283 characters)'
  1529. if test -f 'main.c'
  1530. then
  1531.     echo shar: will not over-write existing file "'main.c'"
  1532. else
  1533. cat << \SHAR_EOF > 'main.c'
  1534. /*    File main.c: 2.7 (84/11/28,10:14:56) */
  1535. /*% cc -O -c %
  1536.  *
  1537.  */
  1538.  
  1539. #include <stdio.h>
  1540. #include "defs.h"
  1541. #include "data.h"
  1542.  
  1543. main (argc, argv)
  1544. int    argc, *argv;
  1545. {
  1546.     char    *p,*bp;
  1547.     int smacptr;
  1548.     macptr = 0;
  1549.     ctext = 0;
  1550.     argc--; argv++;
  1551.     errs = 0;
  1552.     aflag = 1;
  1553.     while (p = *argv++)
  1554.         if (*p == '-') while (*++p)
  1555.             switch(*p) {
  1556.                 case 't': case 'T':
  1557.                     ctext = 1;
  1558.                     break;
  1559.                 case 's': case 'S':
  1560.                     sflag = 1;
  1561.                     break;
  1562.                 case 'c': case 'C':
  1563.                     cflag = 1;
  1564.                     break;
  1565.                 case 'a': case 'A':
  1566.                     aflag = 0;
  1567.                     break;
  1568.                 case 'd': case 'D':
  1569.                     bp = ++p;
  1570.                     if (!*p) usage();
  1571.                     while (*p && *p != '=') p++;
  1572.                     if (*p == '=') *p = '\t';
  1573.                     while (*p) p++;
  1574.                     p--;
  1575.                     defmac(bp);
  1576.                     break;
  1577.                 default:
  1578.                     usage();
  1579.             }
  1580.             else break;
  1581.  
  1582.     smacptr = macptr;
  1583.     if (!p)
  1584.         usage();
  1585.     while (p) {
  1586.         errfile = 0;
  1587.         if (typeof(p) == 'c') {
  1588.             glbptr = STARTGLB;
  1589.             locptr = STARTLOC;
  1590.             wsptr = ws;
  1591.             inclsp =
  1592.             iflevel =
  1593.             skiplevel =
  1594.             swstp =
  1595.             litptr =
  1596.             stkp =
  1597.             errcnt =
  1598.             ncmp =
  1599.             lastst =
  1600.             quote[1] =
  1601.             0;
  1602.             macptr = smacptr;
  1603.             input2 = NULL;
  1604.             quote[0] = '"';
  1605.             cmode = 1;
  1606.             glbflag = 1;
  1607.             nxtlab = 0;
  1608.             litlab = getlabel ();
  1609.             defmac("end\tmemory");
  1610.             addglb("memory", ARRAY, CCHAR, 0, EXTERN);
  1611.             addglb("stack", ARRAY, CCHAR, 0, EXTERN);
  1612.             rglbptr = glbptr;
  1613.             addglb ("etext", ARRAY, CCHAR, 0, EXTERN);
  1614.             addglb ("edata", ARRAY, CCHAR, 0, EXTERN);
  1615.             defmac("short\tint");
  1616.             initmac();
  1617.             /*
  1618.              *    compiler body
  1619.              */
  1620.             if (!openin (p))
  1621.                 return;
  1622.             if (!openout ())
  1623.                 return;
  1624.             header ();
  1625.             gtext ();
  1626.             parse ();
  1627.             fclose (input);
  1628.             gdata ();
  1629.             dumplits ();
  1630.             dumpglbs ();
  1631.             errorsummary ();
  1632.             trailer ();
  1633.             fclose (output);
  1634.             pl ("");
  1635.             errs = errs || errfile;
  1636. #ifndef    NOASLD
  1637.         }
  1638.         if (!errfile && !sflag)
  1639.             errs = errs || assemble(p);
  1640. #else
  1641.         } else {
  1642.             fputs("Don't understand file ", stderr);
  1643.             fputs(p, stderr);
  1644.             errs = 1;
  1645.         }
  1646. #endif
  1647.         p = *argv++;
  1648.     }
  1649. #ifndef    NOASLD
  1650.     if (!errs && !sflag && !cflag)
  1651.         errs = errs || link();
  1652. #endif
  1653.     exit(errs != 0);
  1654. }
  1655.  
  1656. FEvers()
  1657. {
  1658.     outstr("\tFront End (2.7,84/11/28)");
  1659. }
  1660.  
  1661. usage()
  1662. {
  1663.     fputs("usage: sccXXXX [-tcsa] [-dSYM[=VALUE]] files\n", stderr);
  1664.     exit(1);
  1665. }
  1666.  
  1667. /*
  1668.  *    process all input text
  1669.  *
  1670.  *    at this level, only static declarations, defines, includes,
  1671.  *    and function definitions are legal.
  1672.  *
  1673.  */
  1674. parse ()
  1675. {
  1676.     while (!feof (input)) {
  1677.         if (amatch ("extern", 6))
  1678.             dodcls(EXTERN);
  1679.         else if (amatch ("static",6))
  1680.             dodcls(STATIC);
  1681.         else if (dodcls(PUBLIC)) ;
  1682.         else if (match ("#asm"))
  1683.             doasm ();
  1684.         else if (match ("#include"))
  1685.             doinclude ();
  1686.         else if (match ("#define"))
  1687.             dodefine();
  1688.         else if (match ("#undef"))
  1689.             doundef();
  1690.         else
  1691.             newfunc ();
  1692.         blanks ();
  1693.     }
  1694. }
  1695.  
  1696. /*
  1697.  *        parse top level declarations
  1698.     */
  1699.  
  1700. dodcls(stclass)
  1701. int stclass; {
  1702.     blanks();
  1703.     if (amatch("char", 4))
  1704.         declglb(CCHAR, stclass);
  1705.     else if (amatch("int", 3))
  1706.         declglb(CINT, stclass);
  1707.     else if (stclass == PUBLIC)
  1708.         return(0);
  1709.     else
  1710.         declglb(CINT, stclass);
  1711.     ns ();
  1712.     return(1);
  1713. }
  1714.  
  1715.  
  1716. /*
  1717.  *    dump the literal pool
  1718.  */
  1719. dumplits ()
  1720. {
  1721.     int    j, k;
  1722.  
  1723.     if (litptr == 0)
  1724.         return;
  1725.     printlabel (litlab);
  1726.     col ();
  1727.     k = 0;
  1728.     while (k < litptr) {
  1729.         defbyte ();
  1730.         j = 8;
  1731.         while (j--) {
  1732.             onum (litq[k++] & 127);
  1733.             if ((j == 0) | (k >= litptr)) {
  1734.                 nl ();
  1735.                 break;
  1736.             }
  1737.             outbyte (',');
  1738.         }
  1739.     }
  1740. }
  1741.  
  1742. /*
  1743.  *    dump all static variables
  1744.  */
  1745. dumpglbs ()
  1746. {
  1747.     int    j;
  1748.  
  1749.     if (!glbflag)
  1750.         return;
  1751.     cptr = rglbptr;
  1752.     while (cptr < glbptr) {
  1753.         if (cptr[IDENT] != FUNCTION) {
  1754.             ppubext(cptr);
  1755.             if (cptr[STORAGE] != EXTERN) {
  1756.                 prefix ();
  1757.                 outstr (cptr);
  1758.                 col ();
  1759.                 defstorage ();
  1760.                 j = glint(cptr);
  1761.                 if ((cptr[TYPE] == CINT) ||
  1762.                     (cptr[IDENT] == POINTER))
  1763.                     j = j * intsize();
  1764.                 onum (j);
  1765.                 nl ();
  1766.             }
  1767.         } else {
  1768.             fpubext(cptr);
  1769.         }
  1770.         cptr = cptr + SYMSIZ;
  1771.     }
  1772. }
  1773.  
  1774. /*
  1775.  *    report errors
  1776.  */
  1777. errorsummary ()
  1778. {
  1779.     if (ncmp)
  1780.         error ("missing closing bracket");
  1781.     nl ();
  1782.     comment ();
  1783.     outdec (errcnt);
  1784.     if (errcnt) errfile = YES;
  1785.     outstr (" error(s) in compilation");
  1786.     nl ();
  1787.     comment();
  1788.     ot("literal pool:");
  1789.     outdec(litptr);
  1790.     nl();
  1791.     comment();
  1792.     ot("global pool:");
  1793.     outdec(glbptr-rglbptr);
  1794.     nl();
  1795.     comment();
  1796.     ot("Macro pool:");
  1797.     outdec(macptr);
  1798.     nl();
  1799.     pl (errcnt ? "Error(s)" : "No errors");
  1800. }
  1801.  
  1802. typeof(s)
  1803. char    *s; {
  1804.     s += strlen(s) - 2;
  1805.     if (*s == '.')
  1806.         return(*(s+1));
  1807.     return(' ');
  1808. }
  1809. SHAR_EOF
  1810. if test 4283 -ne "`wc -c < 'main.c'`"
  1811. then
  1812.     echo shar: error transmitting "'main.c'" '(should have been 4283 characters)'
  1813. fi
  1814. fi
  1815. echo shar: extracting "'preproc.c'" '(5137 characters)'
  1816. if test -f 'preproc.c'
  1817. then
  1818.     echo shar: will not over-write existing file "'preproc.c'"
  1819. else
  1820. cat << \SHAR_EOF > 'preproc.c'
  1821. /*    File preproc.c: 2.3 (84/11/27,11:47:40) */
  1822. /*% cc -O -c %
  1823.  *
  1824.  */
  1825.  
  1826. #include <stdio.h>
  1827. #include "defs.h"
  1828. #include "data.h"
  1829.  
  1830. /*
  1831.  *    open an include file
  1832.  */
  1833. doinclude ()
  1834. {
  1835.     char    *p;
  1836.     FILE    *inp2;
  1837.  
  1838.     blanks ();
  1839.     if (inp2 = fixiname ())
  1840.         if (inclsp < INCLSIZ) {
  1841.             inclstk[inclsp++] = input2;
  1842.             input2 = inp2;
  1843.         } else {
  1844.             fclose (inp2);
  1845.             error ("too many nested includes");
  1846.         }
  1847.     else {
  1848.         error ("Could not open include file");
  1849.     }
  1850.     kill ();
  1851. }
  1852.  
  1853. /*
  1854.  *    fixiname - remove "brackets" around include file name
  1855.  */
  1856. fixiname ()
  1857. {
  1858.     char    c1, c2, *p, *ibp;
  1859.     char buf[20];
  1860.     FILE *fp;
  1861.     char buf2[100];
  1862.  
  1863.     ibp = &buf[0];
  1864.  
  1865.     if ((c1 = gch ()) != '"' && c1 != '<')
  1866.         return (NULL);
  1867.     for (p = line + lptr; *p ;)
  1868.         *ibp++ = *p++;
  1869.     c2 = *(--p);
  1870.     if (c1 == '"' ? (c2 != '"') : (c2 != '>')) {
  1871.         error ("incorrect delimiter");
  1872.         return (NULL);
  1873.     }
  1874.     *(--ibp) = 0;
  1875.     fp = NULL;
  1876.     if (c1 == '<' || !(fp = fopen(buf, "r"))) {
  1877.         strcpy(buf2, DEFLIB);
  1878.         strcat(buf2, buf);
  1879.         fp = fopen(buf2, "r");
  1880.     }
  1881.     return(fp);
  1882. }
  1883.  
  1884. /*
  1885.  *    "asm" pseudo-statement
  1886.  *
  1887.  *    enters mode where assembly language statements are passed
  1888.  *    intact through parser
  1889.  *
  1890.  */
  1891. doasm ()
  1892. {
  1893.     cmode = 0;
  1894.     FOREVER {
  1895.         inline ();
  1896.         if (match ("#endasm"))
  1897.             break;
  1898.         if (feof (input))
  1899.             break;
  1900.         outstr (line);
  1901.         nl ();
  1902.     }
  1903.     kill ();
  1904.     cmode = 1;
  1905. }
  1906.  
  1907. dodefine ()
  1908. {
  1909.     addmac();
  1910. }
  1911.  
  1912. doundef ()
  1913. {
  1914.     int    mp;
  1915.     char    sname[NAMESIZE];
  1916.  
  1917.     if (!symname(sname)) {
  1918.         illname();
  1919.         kill();
  1920.         return;
  1921.     }
  1922.  
  1923.     if (mp = findmac(sname))
  1924.         delmac(mp);
  1925.     kill();
  1926. }
  1927.  
  1928. preprocess ()
  1929. {
  1930.     if (ifline()) return;
  1931.     while (cpp());
  1932. }
  1933.  
  1934. doifdef (ifdef)
  1935. int ifdef;
  1936. {
  1937.     char sname[NAMESIZE];
  1938.     int k;
  1939.  
  1940.     blanks();
  1941.     ++iflevel;
  1942.     if (skiplevel) return;
  1943.     k = symname(sname) && findmac(sname);
  1944.     if (k != ifdef) skiplevel = iflevel;
  1945. }
  1946.  
  1947. ifline()
  1948. {
  1949.     FOREVER {
  1950.         inline();
  1951.         if (feof(input)) return(1);
  1952.         if (match("#ifdef")) {
  1953.             doifdef(YES);
  1954.             continue;
  1955.         } else if (match("#ifndef")) {
  1956.             doifdef(NO);
  1957.             continue;
  1958.         } else if (match("#else")) {
  1959.             if (iflevel) {
  1960.                 if (skiplevel == iflevel) skiplevel = 0;
  1961.                 else if (skiplevel == 0) skiplevel = iflevel;
  1962.             } else noiferr();
  1963.             continue;
  1964.         } else if (match("#endif")) {
  1965.             if (iflevel) {
  1966.                 if (skiplevel == iflevel) skiplevel = 0;
  1967.                 --iflevel;
  1968.             } else noiferr();
  1969.             continue;
  1970.         }
  1971.         if (!skiplevel) return(0);
  1972.     }
  1973. }
  1974.  
  1975. noiferr()
  1976. {
  1977.     error("no matching #if...");
  1978. }
  1979.  
  1980.  
  1981. cpp ()
  1982. {
  1983.     int    k;
  1984.     char    c, sname[NAMESIZE];
  1985.     int    tog;
  1986.     int    cpped;        /* non-zero if something expanded */
  1987.  
  1988.     cpped = 0;
  1989.     /* don't expand lines with preprocessor commands in them */
  1990.     if (!cmode || line[0] == '#') return(0);
  1991.  
  1992.     mptr = lptr = 0;
  1993.     while (ch ()) {
  1994.         if ((ch () == ' ') | (ch () == 9)) {
  1995.             keepch (' ');
  1996.             while ((ch () == ' ') | (ch () == 9))
  1997.                 gch ();
  1998.         } else if (ch () == '"') {
  1999.             keepch (ch ());
  2000.             gch ();
  2001.             while (ch () != '"') {
  2002.                 if (ch () == 0) {
  2003.                     error ("missing quote");
  2004.                     break;
  2005.                 }
  2006.                 if (ch() == '\\') keepch(gch());
  2007.                 keepch (gch ());
  2008.             }
  2009.             gch ();
  2010.             keepch ('"');
  2011.         } else if (ch () == 39) {
  2012.             keepch (39);
  2013.             gch ();
  2014.             while (ch () != 39) {
  2015.                 if (ch () == 0) {
  2016.                     error ("missing apostrophe");
  2017.                     break;
  2018.                 }
  2019.                 if (ch() == '\\') keepch(gch());
  2020.                 keepch (gch ());
  2021.             }
  2022.             gch ();
  2023.             keepch (39);
  2024.         } else if ((ch () == '/') & (nch () == '*')) {
  2025.             inchar ();
  2026.             inchar ();
  2027.             while ((((c = ch ()) == '*') & (nch () == '/')) == 0)
  2028.                 if (c == '$') {
  2029.                     inchar ();
  2030.                     tog = TRUE;
  2031.                     if (ch () == '-') {
  2032.                         tog = FALSE;
  2033.                         inchar ();
  2034.                     }
  2035.                     if (alpha (c = ch ())) {
  2036.                         inchar ();
  2037.                         toggle (c, tog);
  2038.                     }
  2039.                 } else {
  2040.                     if (ch () == 0)
  2041.                         inline ();
  2042.                     else
  2043.                         inchar ();
  2044.                     if (feof (input))
  2045.                         break;
  2046.                 }
  2047.             inchar ();
  2048.             inchar ();
  2049.         } else if (an (ch ())) {
  2050.             k = 0;
  2051.             while (an (ch ())) {
  2052.                 if (k < NAMEMAX)
  2053.                     sname[k++] = ch ();
  2054.                 gch ();
  2055.             }
  2056.             sname[k] = 0;
  2057.             if (k = findmac (sname)) {
  2058.                 cpped = 1;
  2059.                 while (c = macq[k++])
  2060.                     keepch (c);
  2061.             } else {
  2062.                 k = 0;
  2063.                 while (c = sname[k++])
  2064.                     keepch (c);
  2065.             }
  2066.         } else
  2067.             keepch (gch ());
  2068.     }
  2069.     keepch (0);
  2070.     if (mptr >= MPMAX)
  2071.         error ("line too long");
  2072.     lptr = mptr = 0;
  2073.     while (line[lptr++] = mline[mptr++]);
  2074.     lptr = 0;
  2075.     return(cpped);
  2076. }
  2077.  
  2078. keepch (c)
  2079. char    c;
  2080. {
  2081.     mline[mptr] = c;
  2082.     if (mptr < MPMAX)
  2083.         mptr++;
  2084.     return (c);
  2085. }
  2086.  
  2087. defmac(s)
  2088. char *s;
  2089. {
  2090.     kill();
  2091.     strcpy(line, s);
  2092.     addmac();
  2093. }
  2094.  
  2095. addmac ()
  2096. {
  2097.     char    sname[NAMESIZE];
  2098.     int    k;
  2099.     int    mp;
  2100.  
  2101.     if (!symname (sname)) {
  2102.         illname ();
  2103.         kill ();
  2104.         return;
  2105.     }
  2106.     if (mp = findmac(sname)) {
  2107.         error("Duplicate define");
  2108.         delmac(mp);
  2109.     }
  2110.     k = 0;
  2111.     while (putmac (sname[k++]));
  2112.     while (ch () == ' ' | ch () == 9)
  2113.         gch ();
  2114.     while (putmac (gch ()));
  2115.     if (macptr >= MACMAX)
  2116.         error ("macro table full");
  2117. }
  2118.  
  2119. delmac(mp) int mp; {
  2120.     --mp; --mp;    /* step over previous null */
  2121.     while (mp >= 0 && macq[mp]) macq[mp--] = '%';
  2122. }
  2123.     
  2124.  
  2125. putmac (c)
  2126. char    c;
  2127. {
  2128.     macq[macptr] = c;
  2129.     if (macptr < MACMAX)
  2130.         macptr++;
  2131.     return (c);
  2132. }
  2133.  
  2134. findmac (sname)
  2135. char    *sname;
  2136. {
  2137.     int    k;
  2138.  
  2139.     k = 0;
  2140.     while (k < macptr) {
  2141.         if (astreq (sname, macq + k, NAMEMAX)) {
  2142.             while (macq[k++]);
  2143.             return (k);
  2144.         }
  2145.         while (macq[k++]);
  2146.         while (macq[k++]);
  2147.     }
  2148.     return (0);
  2149. }
  2150.  
  2151. toggle (name, onoff)
  2152. char    name;
  2153. int    onoff;
  2154. {
  2155.     switch (name) {
  2156.     case 'C':
  2157.         ctext = onoff;
  2158.         break;
  2159.     }
  2160. }
  2161. SHAR_EOF
  2162. if test 5137 -ne "`wc -c < 'preproc.c'`"
  2163. then
  2164.     echo shar: error transmitting "'preproc.c'" '(should have been 5137 characters)'
  2165. fi
  2166. fi
  2167. echo shar: extracting "'primary.c'" '(4818 characters)'
  2168. if test -f 'primary.c'
  2169. then
  2170.     echo shar: will not over-write existing file "'primary.c'"
  2171. else
  2172. cat << \SHAR_EOF > 'primary.c'
  2173. /*    File primary.c: 2.4 (84/11/27,16:26:07) */
  2174. /*% cc -O -c %
  2175.  *
  2176.  */
  2177.  
  2178. #include <stdio.h>
  2179. #include "defs.h"
  2180. #include "data.h"
  2181.  
  2182. primary (lval)
  2183. int    *lval;
  2184. {
  2185.     char    *ptr, sname[NAMESIZE];
  2186.     int    num[1];
  2187.     int    k;
  2188.  
  2189.     lval[2] = 0;  /* clear pointer/array type */
  2190.     if (match ("(")) {
  2191.         k = heir1 (lval);
  2192.         needbrack (")");
  2193.         return (k);
  2194.     }
  2195.     if (amatch("sizeof", 6)) {
  2196.         needbrack("(");
  2197.         immed();
  2198.         if (amatch("int", 3)) onum(intsize());
  2199.         else if (amatch("char", 4)) onum(1);
  2200.         else if (symname(sname)) {
  2201.             if ((ptr = findloc(sname)) ||
  2202.                 (ptr = findglb(sname))) {
  2203.                 if (ptr[STORAGE] == LSTATIC)
  2204.                     error("sizeof local static");
  2205.                 k = glint(ptr);
  2206.                 if ((ptr[TYPE] == CINT) ||
  2207.                     (ptr[IDENT] == POINTER))
  2208.                     k *= intsize();
  2209.                 onum(k);
  2210.             } else {
  2211.                 error("sizeof undeclared variable");
  2212.                 onum(0);
  2213.             }
  2214.         } else {
  2215.             error("sizeof only on type or variable");
  2216.         }
  2217.         needbrack(")");
  2218.         nl();
  2219.         return(lval[0] = lval[1] = 0);
  2220.     }
  2221.     if (symname (sname)) {
  2222.         if (ptr = findloc (sname)) {
  2223.             getloc (ptr);
  2224.             lval[0] = ptr;
  2225.             lval[1] =  ptr[TYPE];
  2226.             if (ptr[IDENT] == POINTER) {
  2227.                 lval[1] = CINT;
  2228.                 lval[2] = ptr[TYPE];
  2229.             }
  2230.             if (ptr[IDENT] == ARRAY) {
  2231.                 lval[2] = ptr[TYPE];
  2232.                 lval[2] = 0;
  2233.                 return (0);
  2234.             }
  2235.             else
  2236.                 return (1);
  2237.         }
  2238.         if (ptr = findglb (sname))
  2239.             if (ptr[IDENT] != FUNCTION) {
  2240.                 lval[0] = ptr;
  2241.                 lval[1] = 0;
  2242.                 if (ptr[IDENT] != ARRAY) {
  2243.                     if (ptr[IDENT] == POINTER)
  2244.                         lval[2] = ptr[TYPE];
  2245.                     return (1);
  2246.                 }
  2247.                 immed ();
  2248.                 prefix ();
  2249.                 outstr (ptr);
  2250.                 nl ();
  2251.                 lval[1] = lval[2] = ptr[TYPE];
  2252.                 lval[2] = 0;
  2253.                 return (0);
  2254.             }
  2255.         blanks ();
  2256.         if (ch() != '(')
  2257.             error("undeclared variable");
  2258.         ptr = addglb (sname, FUNCTION, CINT, 0, PUBLIC);
  2259.         lval[0] = ptr;
  2260.         lval[1] = 0;
  2261.         return (0);
  2262.     }
  2263.     if (constant (num))
  2264.         return (lval[0] = lval[1] = 0);
  2265.     else {
  2266.         error ("invalid expression");
  2267.         immed ();
  2268.         onum (0);
  2269.         nl ();
  2270.         junk ();
  2271.         return (0);
  2272.     }
  2273. }
  2274.  
  2275. /*
  2276.  *    true if val1 -> int pointer or int array and val2 not pointer or array
  2277.  */
  2278. dbltest (val1, val2)
  2279. int    val1[], val2[];
  2280. {
  2281.     if (val1 == NULL)
  2282.         return (FALSE);
  2283.     if (val1[2] != CINT)
  2284.         return (FALSE);
  2285.     if (val2[2])
  2286.         return (FALSE);
  2287.     return (TRUE);
  2288. }
  2289.  
  2290. /*
  2291.  *    determine type of binary operation
  2292.  */
  2293. result (lval, lval2)
  2294. int    lval[],
  2295.     lval2[];
  2296. {
  2297.     if (lval[2] && lval2[2])
  2298.         lval[2] = 0;
  2299.     else if (lval2[2]) {
  2300.         lval[0] = lval2[0];
  2301.         lval[1] = lval2[1];
  2302.         lval[2] = lval2[2];
  2303.     }
  2304. }
  2305.         
  2306. constant (val)
  2307. int    val[];
  2308. {
  2309.     if (number (val))
  2310.         immed ();
  2311.     else if (pstr (val))
  2312.         immed ();
  2313.     else if (qstr (val)) {
  2314.         immed ();
  2315.         printlabel (litlab);
  2316.         outbyte ('+');
  2317.     } else
  2318.         return (0);
  2319.     onum (val[0]);
  2320.     nl ();
  2321.     return (1);
  2322. }
  2323.  
  2324. number (val)
  2325. int    val[];
  2326. {
  2327.     int    k, minus, base;
  2328.     char    c;
  2329.  
  2330.     k = minus = 1;
  2331.     while (k) {
  2332.         k = 0;
  2333.         if (match ("+"))
  2334.             k = 1;
  2335.         if (match ("-")) {
  2336.             minus = (-minus);
  2337.             k = 1;
  2338.         }
  2339.     }
  2340.     if (!numeric (c = ch ()))
  2341.         return (0);
  2342.     if (match ("0x") || match ("0X"))
  2343.         while (numeric (c = ch ()) ||
  2344.                (c >= 'a' && c <= 'f') ||
  2345.                (c >= 'A' && c <= 'F')) {
  2346.             inbyte ();
  2347.             k = k * 16 +
  2348.                 (numeric (c) ? (c - '0') : ((c & 07) + 9));
  2349.         }
  2350.     else {
  2351.         base = (c == '0') ? 8 : 10;
  2352.         while (numeric (ch ())) {
  2353.             c = inbyte ();
  2354.             k = k * base + (c - '0');
  2355.         }
  2356.     }
  2357.     if (minus < 0)
  2358.         k = (-k);
  2359.     val[0] = k;
  2360.     return (1);
  2361. }
  2362.  
  2363. pstr (val)
  2364. int    val[];
  2365. {
  2366.     int    k;
  2367.     char    c;
  2368.  
  2369.     k = 0;
  2370.     if (!match ("'"))
  2371.         return (0);
  2372.     while ((c = gch ()) != 39) {
  2373.         c = (c == '\\') ? spechar(): c;
  2374.         k = (k & 255) * 256 + (c & 255);
  2375.     }
  2376.     val[0] = k;
  2377.     return (1);
  2378. }
  2379.  
  2380. qstr (val)
  2381. int    val[];
  2382. {
  2383.     char    c;
  2384.  
  2385.     if (!match (quote))
  2386.         return (0);
  2387.     val[0] = litptr;
  2388.     while (ch () != '"') {
  2389.         if (ch () == 0)
  2390.             break;
  2391.         if (litptr >= LITMAX) {
  2392.             error ("string space exhausted");
  2393.             while (!match (quote))
  2394.                 if (gch () == 0)
  2395.                     break;
  2396.             return (1);
  2397.         }
  2398.         c = gch();
  2399.         litq[litptr++] = (c == '\\') ? spechar(): c;
  2400.     }
  2401.     gch ();
  2402.     litq[litptr++] = 0;
  2403.     return (1);
  2404. }
  2405.  
  2406. /*
  2407.  *    decode special characters (preceeded by back slashes)
  2408.  */
  2409. spechar() {
  2410.     char c;
  2411.     c = ch();
  2412.  
  2413.     if    (c == 'n') c = EOL;
  2414.     else if    (c == 't') c = TAB;
  2415.     else if (c == 'r') c = CR;
  2416.     else if (c == 'f') c = FFEED;
  2417.     else if (c == 'b') c = BKSP;
  2418.     else if (c == '0') c = EOS;
  2419.     else if (c == EOS) return;
  2420.  
  2421.     gch();
  2422.     return (c);
  2423. }
  2424.  
  2425. /*
  2426.  *    perform a function call
  2427.  *
  2428.  *    called from "heir11", this routine will either call the named
  2429.  *    function, or if the supplied ptr is zero, will call the contents
  2430.  *    of HL
  2431.  *
  2432.  */
  2433. callfunction (ptr)
  2434. char    *ptr;
  2435. {
  2436.     int    nargs;
  2437.  
  2438.     nargs = 0;
  2439.     blanks ();
  2440.     if (ptr == 0)
  2441.         gpush ();
  2442.     while (!streq (line + lptr, ")")) {
  2443.         if (endst ())
  2444.             break;
  2445.         expression (NO);
  2446.         if (ptr == 0)
  2447.             swapstk ();
  2448.         gpush ();
  2449.         nargs = nargs + intsize();
  2450.         if (!match (","))
  2451.             break;
  2452.     }
  2453.     needbrack (")");
  2454.     if (aflag)
  2455.         gnargs(nargs / intsize());
  2456.     if (ptr)
  2457.         gcall (ptr);
  2458.     else
  2459.         callstk ();
  2460.     stkp = modstk (stkp + nargs);
  2461. }
  2462.  
  2463. needlval ()
  2464. {
  2465.     error ("must be lvalue");
  2466. }
  2467. SHAR_EOF
  2468. if test 4818 -ne "`wc -c < 'primary.c'`"
  2469. then
  2470.     echo shar: error transmitting "'primary.c'" '(should have been 4818 characters)'
  2471. fi
  2472. fi
  2473. echo shar: extracting "'stmt.c'" '(6668 characters)'
  2474. if test -f 'stmt.c'
  2475. then
  2476.     echo shar: will not over-write existing file "'stmt.c'"
  2477. else
  2478. cat << \SHAR_EOF > 'stmt.c'
  2479. /*    File stmt.c: 2.1 (83/03/20,16:02:17) */
  2480. /*% cc -O -c %
  2481.  *
  2482.  */
  2483.  
  2484. #include <stdio.h>
  2485. #include "defs.h"
  2486. #include "data.h"
  2487.  
  2488. /*
  2489.  *    statement parser
  2490.  *
  2491.  *    called whenever syntax requires a statement.  this routine
  2492.  *    performs that statement and returns a number telling which one
  2493.  *
  2494.  *    'func' is true if we require a "function_statement", which
  2495.  *    must be compound, and must contain "statement_list" (even if
  2496.  *    "declaration_list" is omitted)
  2497.  */
  2498.  
  2499. statement (func)
  2500. int    func;
  2501. {
  2502.     if ((ch () == 0) & feof (input))
  2503.         return (0);
  2504.     lastst = 0;
  2505.     if (func)
  2506.         if (match ("{")) {
  2507.             compound (YES);
  2508.             return (lastst);
  2509.         } else
  2510.             error ("function requires compound statement");
  2511.     if (match ("{"))
  2512.         compound (NO);
  2513.     else
  2514.         stst ();
  2515.     return (lastst);
  2516. }
  2517.  
  2518. /*
  2519.  *    declaration
  2520.  */
  2521. stdecl ()
  2522. {
  2523.     if (amatch("register", 8))
  2524.         doldcls(DEFAUTO);
  2525.     else if (amatch("auto", 4))
  2526.         doldcls(DEFAUTO);
  2527.     else if (amatch("static", 6))
  2528.         doldcls(LSTATIC);
  2529.     else if (doldcls(AUTO)) ;
  2530.     else
  2531.         return (NO);
  2532.     return (YES);
  2533. }
  2534.  
  2535. doldcls(stclass)
  2536. int    stclass;
  2537. {
  2538.     blanks();
  2539.     if (amatch("char", 4))
  2540.         declloc(CCHAR, stclass);
  2541.     else if (amatch("int", 3))
  2542.         declloc(CINT, stclass);
  2543.     else if (stclass == LSTATIC || stclass == DEFAUTO)
  2544.         declloc(CINT, stclass);
  2545.     else
  2546.         return(0);
  2547.     ns();
  2548.     return(1);
  2549. }
  2550.  
  2551.  
  2552. /*
  2553.  *    non-declaration statement
  2554.  */
  2555. stst ()
  2556. {
  2557.     if (amatch ("if", 2)) {
  2558.         doif ();
  2559.         lastst = STIF;
  2560.     } else if (amatch ("while", 5)) {
  2561.         dowhile ();
  2562.         lastst = STWHILE;
  2563.     } else if (amatch ("switch", 6)) {
  2564.         doswitch ();
  2565.         lastst = STSWITCH;
  2566.     } else if (amatch ("do", 2)) {
  2567.         dodo ();
  2568.         ns ();
  2569.         lastst = STDO;
  2570.     } else if (amatch ("for", 3)) {
  2571.         dofor ();
  2572.         lastst = STFOR;
  2573.     } else if (amatch ("return", 6)) {
  2574.         doreturn ();
  2575.         ns ();
  2576.         lastst = STRETURN;
  2577.     } else if (amatch ("break", 5)) {
  2578.         dobreak ();
  2579.         ns ();
  2580.         lastst = STBREAK;
  2581.     } else if (amatch ("continue", 8)) {
  2582.         docont ();
  2583.         ns ();
  2584.         lastst = STCONT;
  2585.     } else if (match (";"))
  2586.         ;
  2587.     else if (amatch ("case", 4)) {
  2588.         docase ();
  2589.         lastst = statement (NO);
  2590.     } else if (amatch ("default", 7)) {
  2591.         dodefault ();
  2592.         lastst = statement (NO);
  2593.     } else if (match ("#asm")) {
  2594.         doasm ();
  2595.         lastst = STASM;
  2596.     } else if (match ("{"))
  2597.         compound (NO);
  2598.     else {
  2599.         expression (YES);
  2600. /*        if (match (":")) {
  2601.             dolabel ();
  2602.             lastst = statement (NO);
  2603.         } else {
  2604. */            ns ();
  2605.             lastst = STEXP;
  2606. /*        }
  2607. */    }
  2608. }
  2609.  
  2610. /*
  2611.  *    compound statement
  2612.  *
  2613.  *    allow any number of statements to fall between "{" and "}"
  2614.  *
  2615.  *    'func' is true if we are in a "function_statement", which
  2616.  *    must contain "statement_list"
  2617.  */
  2618. compound (func)
  2619. int    func;
  2620. {
  2621.     int    decls;
  2622.  
  2623.     decls = YES;
  2624.     ncmp++;
  2625.     while (!match ("}")) {
  2626.         if (feof (input))
  2627.             return;
  2628.         if (decls) {
  2629.             if (!stdecl ())
  2630.                 decls = NO;
  2631.         } else
  2632.             stst ();
  2633.     }
  2634.     ncmp--;
  2635. }
  2636.  
  2637. /*
  2638.  *    "if" statement
  2639.  */
  2640. doif ()
  2641. {
  2642.     int    fstkp, flab1, flab2;
  2643.     char    *flev;
  2644.  
  2645.     flev = locptr;
  2646.     fstkp = stkp;
  2647.     flab1 = getlabel ();
  2648.     test (flab1, FALSE);
  2649.     statement (NO);
  2650.     stkp = modstk (fstkp);
  2651.     locptr = flev;
  2652.     if (!amatch ("else", 4)) {
  2653.         gnlabel (flab1);
  2654.         return;
  2655.     }
  2656.     jump (flab2 = getlabel ());
  2657.     gnlabel (flab1);
  2658.     statement (NO);
  2659.     stkp = modstk (fstkp);
  2660.     locptr = flev;
  2661.     gnlabel (flab2);
  2662. }
  2663.  
  2664. /*
  2665.  *    "while" statement
  2666.  */
  2667. dowhile ()
  2668. {
  2669.     int    ws[7];
  2670.  
  2671.     ws[WSSYM] = locptr;
  2672.     ws[WSSP] = stkp;
  2673.     ws[WSTYP] = WSWHILE;
  2674.     ws[WSTEST] = getlabel ();
  2675.     ws[WSEXIT] = getlabel ();
  2676.     addwhile (ws);
  2677.     gnlabel (ws[WSTEST]);
  2678.     test (ws[WSEXIT], FALSE);
  2679.     statement (NO);
  2680.     jump (ws[WSTEST]);
  2681.     gnlabel (ws[WSEXIT]);
  2682.     locptr = ws[WSSYM];
  2683.     stkp = modstk (ws[WSSP]);
  2684.     delwhile ();
  2685. }
  2686.  
  2687. /*
  2688.  *    "do" statement
  2689.  */
  2690. dodo ()
  2691. {
  2692.     int    ws[7];
  2693.  
  2694.     ws[WSSYM] = locptr;
  2695.     ws[WSSP] = stkp;
  2696.     ws[WSTYP] = WSDO;
  2697.     ws[WSBODY] = getlabel ();
  2698.     ws[WSTEST] = getlabel ();
  2699.     ws[WSEXIT] = getlabel ();
  2700.     addwhile (ws);
  2701.     gnlabel (ws[WSBODY]);
  2702.     statement (NO);
  2703.     if (!match ("while")) {
  2704.         error ("missing while");
  2705.         return;
  2706.     }
  2707.     gnlabel (ws[WSTEST]);
  2708.     test (ws[WSBODY], TRUE);
  2709.     gnlabel (ws[WSEXIT]);
  2710.     locptr = ws[WSSYM];
  2711.     stkp = modstk (ws[WSSP]);
  2712.     delwhile ();
  2713. }
  2714.  
  2715. /*
  2716.  *    "for" statement
  2717.  */
  2718. dofor ()
  2719. {
  2720.     int    ws[7],
  2721.         *pws;
  2722.  
  2723.     ws[WSSYM] = locptr;
  2724.     ws[WSSP] = stkp;
  2725.     ws[WSTYP] = WSFOR;
  2726.     ws[WSTEST] = getlabel ();
  2727.     ws[WSINCR] = getlabel ();
  2728.     ws[WSBODY] = getlabel ();
  2729.     ws[WSEXIT] = getlabel ();
  2730.     addwhile (ws);
  2731.     pws = readwhile ();
  2732.     needbrack ("(");
  2733.     if (!match (";")) {
  2734.         expression (YES);
  2735.         ns ();
  2736.     }
  2737.     gnlabel (pws[WSTEST]);
  2738.     if (!match (";")) {
  2739.         expression (YES);
  2740.         testjump (pws[WSBODY], TRUE);
  2741.         jump (pws[WSEXIT]);
  2742.         ns ();
  2743.     } else
  2744.         pws[WSTEST] = pws[WSBODY];
  2745.     gnlabel (pws[WSINCR]);
  2746.     if (!match (")")) {
  2747.         expression (YES);
  2748.         needbrack (")");
  2749.         jump (pws[WSTEST]);
  2750.     } else
  2751.         pws[WSINCR] = pws[WSTEST];
  2752.     gnlabel (pws[WSBODY]);
  2753.     statement (NO);
  2754.     jump (pws[WSINCR]);
  2755.     gnlabel (pws[WSEXIT]);
  2756.     locptr = pws[WSSYM];
  2757.     stkp = modstk (pws[WSSP]);
  2758.     delwhile ();
  2759. }
  2760.  
  2761. /*
  2762.  *    "switch" statement
  2763.  */
  2764. doswitch ()
  2765. {
  2766.     int    ws[7];
  2767.     int    *ptr;
  2768.  
  2769.     ws[WSSYM] = locptr;
  2770.     ws[WSSP] = stkp;
  2771.     ws[WSTYP] = WSSWITCH;
  2772.     ws[WSCASEP] = swstp;
  2773.     ws[WSTAB] = getlabel ();
  2774.     ws[WSDEF] = ws[WSEXIT] = getlabel ();
  2775.     addwhile (ws);
  2776.     immed ();
  2777.     printlabel (ws[WSTAB]);
  2778.     nl ();
  2779.     gpush ();
  2780.     needbrack ("(");
  2781.     expression (YES);
  2782.     needbrack (")");
  2783.     stkp = stkp + intsize();  /* '?case' will adjust the stack */
  2784.     gjcase ();
  2785.     statement (NO);
  2786.     ptr = readswitch ();
  2787.     jump (ptr[WSEXIT]);
  2788.     dumpsw (ptr);
  2789.     gnlabel (ptr[WSEXIT]);
  2790.     locptr = ptr[WSSYM];
  2791.     stkp = modstk (ptr[WSSP]);
  2792.     swstp = ptr[WSCASEP];
  2793.     delwhile ();
  2794. }
  2795.  
  2796. /*
  2797.  *    "case" label
  2798.  */
  2799. docase ()
  2800. {
  2801.     int    val;
  2802.  
  2803.     val = 0;
  2804.     if (readswitch ()) {
  2805.         if (!number (&val))
  2806.             if (!pstr (&val))
  2807.                 error ("bad case label");
  2808.         addcase (val);
  2809.         if (!match (":"))
  2810.             error ("missing colon");
  2811.     } else
  2812.         error ("no active switch");
  2813. }
  2814.  
  2815. /*
  2816.  *    "default" label
  2817.  */
  2818. dodefault ()
  2819. {
  2820.     int    *ptr,
  2821.         lab;
  2822.  
  2823.     if (ptr = readswitch ()) {
  2824.         ptr[WSDEF] = lab = getlabel ();
  2825.         gnlabel (lab);
  2826.         if (!match (":"))
  2827.             error ("missing colon");
  2828.     } else
  2829.         error ("no active switch");
  2830. }
  2831.  
  2832. /*
  2833.  *    "return" statement
  2834.  */
  2835. doreturn ()
  2836. {
  2837.     if (endst () == 0)
  2838.         expression (YES);
  2839.     jump(fexitlab);
  2840. }
  2841.  
  2842. /*
  2843.  *    "break" statement
  2844.  */
  2845. dobreak ()
  2846. {
  2847.     int    *ptr;
  2848.  
  2849.     if ((ptr = readwhile ()) == 0)
  2850.         return;
  2851.     modstk (ptr[WSSP]);
  2852.     jump (ptr[WSEXIT]);
  2853. }
  2854.  
  2855. /*
  2856.  *    "continue" statement
  2857.  */
  2858. docont ()
  2859. {
  2860.     int    *ptr;
  2861.  
  2862.     if ((ptr = findwhile ()) == 0)
  2863.         return;
  2864.     modstk (ptr[WSSP]);
  2865.     if (ptr[WSTYP] == WSFOR)
  2866.         jump (ptr[WSINCR]);
  2867.     else
  2868.         jump (ptr[WSTEST]);
  2869. }
  2870.  
  2871. /*
  2872.  *    dump switch table
  2873.  */
  2874. dumpsw (ws)
  2875. int    ws[];
  2876. {
  2877.     int    i,j;
  2878.  
  2879.     gdata ();
  2880.     gnlabel (ws[WSTAB]);
  2881.     if (ws[WSCASEP] != swstp) {
  2882.         j = ws[WSCASEP];
  2883.         while (j < swstp) {
  2884.             defword ();
  2885.             i = 4;
  2886.             while (i--) {
  2887.                 onum (swstcase[j]);
  2888.                 outbyte (',');
  2889.                 printlabel (swstlab[j++]);
  2890.                 if ((i == 0) | (j >= swstp)) {
  2891.                     nl ();
  2892.                     break;
  2893.                 }
  2894.                 outbyte (',');
  2895.             }
  2896.         }
  2897.     }
  2898.     defword ();
  2899.     printlabel (ws[WSDEF]);
  2900.     outstr (",0");
  2901.     nl ();
  2902.     gtext ();
  2903. }
  2904. SHAR_EOF
  2905. if test 6668 -ne "`wc -c < 'stmt.c'`"
  2906. then
  2907.     echo shar: error transmitting "'stmt.c'" '(should have been 6668 characters)'
  2908. fi
  2909. fi
  2910. echo shar: extracting "'sym.c'" '(3849 characters)'
  2911. if test -f 'sym.c'
  2912. then
  2913.     echo shar: will not over-write existing file "'sym.c'"
  2914. else
  2915. cat << \SHAR_EOF > 'sym.c'
  2916. /*    File sym.c: 2.1 (83/03/20,16:02:19) */
  2917. /*% cc -O -c %
  2918.  *
  2919.  */
  2920.  
  2921. #include <stdio.h>
  2922. #include "defs.h"
  2923. #include "data.h"
  2924.  
  2925. /*
  2926.  *    declare a static variable
  2927.  */
  2928. declglb (typ, stor)
  2929. int    typ,
  2930.     stor;
  2931. {
  2932.     int    k, j;
  2933.     char    sname[NAMESIZE];
  2934.  
  2935.     FOREVER {
  2936.         FOREVER {
  2937.             if (endst ())
  2938.                 return;
  2939.             k = 1;
  2940.             if (match ("*"))
  2941.                 j = POINTER;
  2942.             else
  2943.                 j = VARIABLE;
  2944.             if (!symname (sname))
  2945.                 illname ();
  2946.             if (findglb (sname))
  2947.                 multidef (sname);
  2948.             if (match ("[")) {
  2949.                 k = needsub ();
  2950.                 if (k || stor == EXTERN)
  2951.                     j = ARRAY;
  2952.                 else
  2953.                     j = POINTER;
  2954.             }
  2955.             addglb (sname, j, typ, k, stor);
  2956.             break;
  2957.         }
  2958.         if (!match (","))
  2959.             return;
  2960.     }
  2961. }
  2962.  
  2963. /*
  2964.  *    declare local variables
  2965.  *
  2966.  *    works just like "declglb", but modifies machine stack and adds
  2967.  *    symbol table entry with appropriate stack offset to find it again
  2968.  */
  2969. declloc (typ, stclass)
  2970. int    typ, stclass;
  2971. {
  2972.     int    k, j;
  2973.     char    sname[NAMESIZE];
  2974.  
  2975.     FOREVER {
  2976.         FOREVER {
  2977.             if (endst ())
  2978.                 return;
  2979.             if (match ("*"))
  2980.                 j = POINTER;
  2981.             else
  2982.                 j = VARIABLE;
  2983.             if (!symname (sname))
  2984.                 illname ();
  2985.             if (findloc (sname))
  2986.                 multidef (sname);
  2987.             if (match ("[")) {
  2988.                 k = needsub ();
  2989.                 if (k) {
  2990.                     j = ARRAY;
  2991.                     if (typ == CINT)
  2992.                         k = k * intsize();
  2993.                 } else {
  2994.                     j = POINTER;
  2995.                     k = intsize();
  2996.                 }
  2997.             } else
  2998.                 if ((typ == CCHAR) & (j != POINTER))
  2999.                     k = 1;
  3000.                 else
  3001.                     k = intsize();
  3002.             if (stclass != LSTATIC) {
  3003.                 k = galign(k);
  3004.                 stkp = modstk (stkp - k);
  3005.                 addloc (sname, j, typ, stkp, AUTO);
  3006.             } else
  3007.                 addloc( sname, j, typ, k, LSTATIC);
  3008.             break;
  3009.         }
  3010.         if (!match (","))
  3011.             return;
  3012.     }
  3013. }
  3014.  
  3015. /*
  3016.  *    get required array size
  3017.  */
  3018. needsub ()
  3019. {
  3020.     int    num[1];
  3021.  
  3022.     if (match ("]"))
  3023.         return (0);
  3024.     if (!number (num)) {
  3025.         error ("must be constant");
  3026.         num[0] = 1;
  3027.     }
  3028.     if (num[0] < 0) {
  3029.         error ("negative size illegal");
  3030.         num[0] = (-num[0]);
  3031.     }
  3032.     needbrack ("]");
  3033.     return (num[0]);
  3034. }
  3035.  
  3036. findglb (sname)
  3037. char    *sname;
  3038. {
  3039.     char    *ptr;
  3040.  
  3041.     ptr = STARTGLB;
  3042.     while (ptr != glbptr) {
  3043.         if (astreq (sname, ptr, NAMEMAX))
  3044.             return (ptr);
  3045.         ptr = ptr + SYMSIZ;
  3046.     }
  3047.     return (0);
  3048. }
  3049.  
  3050. findloc (sname)
  3051. char    *sname;
  3052. {
  3053.     char    *ptr;
  3054.  
  3055.     ptr = locptr;
  3056.     while (ptr != STARTLOC) {
  3057.         ptr = ptr - SYMSIZ;
  3058.         if (astreq (sname, ptr, NAMEMAX))
  3059.             return (ptr);
  3060.     }
  3061.     return (0);
  3062. }
  3063.  
  3064. addglb (sname, id, typ, value, stor)
  3065. char    *sname, id, typ;
  3066. int    value,
  3067.     stor;
  3068. {
  3069.     char    *ptr;
  3070.  
  3071.     if (cptr = findglb (sname))
  3072.         return (cptr);
  3073.     if (glbptr >= ENDGLB) {
  3074.         error ("global symbol table overflow");
  3075.         return (0);
  3076.     }
  3077.     cptr = ptr = glbptr;
  3078.     while (an (*ptr++ = *sname++));
  3079.     cptr[IDENT] = id;
  3080.     cptr[TYPE] = typ;
  3081.     cptr[STORAGE] = stor;
  3082.     cptr[OFFSET] = value & 0xff;    
  3083.     cptr[OFFSET+1] = (value >> 8) & 0xff;
  3084.     glbptr = glbptr + SYMSIZ;
  3085.     return (cptr);
  3086. }
  3087.  
  3088. addloc (sname, id, typ, value, stclass)
  3089. char    *sname, id, typ;
  3090. int    value, stclass;
  3091. {
  3092.     char    *ptr;
  3093.     int    k;
  3094.  
  3095.     if (cptr = findloc (sname))
  3096.         return (cptr);
  3097.     if (locptr >= ENDLOC) {
  3098.         error ("local symbol table overflow");
  3099.         return (0);
  3100.     }
  3101.     cptr = ptr = locptr;
  3102.     while (an (*ptr++ = *sname++));
  3103.     cptr[IDENT] = id;
  3104.     cptr[TYPE] = typ;
  3105.     cptr[STORAGE] = stclass;
  3106.     if (stclass == LSTATIC) {
  3107.         gdata();
  3108.         printlabel(k = getlabel());
  3109.         col();
  3110.         defstorage();
  3111.         onum(value);
  3112.         nl();
  3113.         gtext();
  3114.         value = k;
  3115.     } else
  3116.         value = galign(value);
  3117.     cptr[OFFSET] = value & 0xff;
  3118.     cptr[OFFSET+1] = (value >> 8) & 0xff;
  3119.     locptr = locptr + SYMSIZ;
  3120.     return (cptr);
  3121. }
  3122.  
  3123. /*
  3124.  *    test if next input string is legal symbol name
  3125.  *
  3126.  */
  3127. symname (sname)
  3128. char    *sname;
  3129. {
  3130.     int    k;
  3131.     char    c;
  3132.  
  3133.     blanks ();
  3134.     if (!alpha (ch ()))
  3135.         return (0);
  3136.     k = 0;
  3137.     while (an (ch ()))
  3138.         sname[k++] = gch ();
  3139.     sname[k] = 0;
  3140.     return (1);
  3141. }
  3142.  
  3143. illname ()
  3144. {
  3145.     error ("illegal symbol name");
  3146. }
  3147.  
  3148. multidef (sname)
  3149. char    *sname;
  3150. {
  3151.     error ("already defined");
  3152.     comment ();
  3153.     outstr (sname);
  3154.     nl ();
  3155. }
  3156.  
  3157. glint(syment) char *syment; {
  3158.     int l,u,r;
  3159.     l = syment[OFFSET];
  3160.     u = syment[OFFSET+1];
  3161.     r = (l & 0xff) + ((u << 8) & ~0x00ff);
  3162.     return (r);
  3163. }
  3164. SHAR_EOF
  3165. if test 3849 -ne "`wc -c < 'sym.c'`"
  3166. then
  3167.     echo shar: error transmitting "'sym.c'" '(should have been 3849 characters)'
  3168. fi
  3169. fi
  3170. echo shar: extracting "'while.c'" '(980 characters)'
  3171. if test -f 'while.c'
  3172. then
  3173.     echo shar: will not over-write existing file "'while.c'"
  3174. else
  3175. cat << \SHAR_EOF > 'while.c'
  3176. /*    File while.c: 2.1 (83/03/20,16:02:22) */
  3177. /*% cc -O -c %
  3178.  *
  3179.  */
  3180.  
  3181. #include <stdio.h>
  3182. #include "defs.h"
  3183. #include "data.h"
  3184.  
  3185. addwhile (ptr)
  3186. int    ptr[];
  3187. {
  3188.     int    k;
  3189.  
  3190.     if (wsptr == WSMAX) {
  3191.         error ("too many active whiles");
  3192.         return;
  3193.     }
  3194.     k = 0;
  3195.     while (k < WSSIZ)
  3196.         *wsptr++ = ptr[k++];
  3197. }
  3198.  
  3199. delwhile ()
  3200. {
  3201.     if (readwhile ())
  3202.         wsptr = wsptr - WSSIZ;
  3203. }
  3204.  
  3205. readwhile ()
  3206. {
  3207.     if (wsptr == ws) {
  3208.         error ("no active do/for/while/switch");
  3209.         return (0);
  3210.     } else
  3211.         return (wsptr-WSSIZ);
  3212. }
  3213.  
  3214. findwhile ()
  3215. {
  3216.     int    *ptr;
  3217.  
  3218.     for (ptr = wsptr; ptr != ws;) {
  3219.         ptr = ptr - WSSIZ;
  3220.         if (ptr[WSTYP] != WSSWITCH)
  3221.             return (ptr);
  3222.     }
  3223.     error ("no active do/for/while");
  3224.     return (0);
  3225. }
  3226.  
  3227. readswitch ()
  3228. {
  3229.     int    *ptr;
  3230.  
  3231.     if (ptr = readwhile ())
  3232.         if (ptr[WSTYP] == WSSWITCH)
  3233.             return (ptr);
  3234.     return (0);
  3235. }
  3236.  
  3237. addcase (val)
  3238. int    val;
  3239. {
  3240.     int    lab;
  3241.  
  3242.     if (swstp == SWSTSZ)
  3243.         error ("too many case labels");
  3244.     else {
  3245.         swstcase[swstp] = val;
  3246.         swstlab[swstp++] = lab = getlabel ();
  3247.         printlabel (lab);
  3248.         col ();
  3249.         nl ();
  3250.     }
  3251. }
  3252. SHAR_EOF
  3253. if test 980 -ne "`wc -c < 'while.c'`"
  3254. then
  3255.     echo shar: error transmitting "'while.c'" '(should have been 980 characters)'
  3256. fi
  3257. fi
  3258. exit 0
  3259. #    End of shell archive
  3260.